package com.dkha.task.service.impl;

import com.dkha.common.modules.vo.camera.BayOnetCameraVO;
import com.dkha.common.modules.vo.camera.PeopleVO;
import com.dkha.common.modules.vo.face.ApiAlarmVO;
import com.dkha.common.redis.RedisKeys;
import com.dkha.common.redis.RedisUtils;
import com.dkha.common.util.TimeUtil;
import com.dkha.common.util.UtilValidate;
import com.dkha.task.comm.TimerData;
import com.dkha.task.modual.entity.FaceTrackEntity;
import com.dkha.task.service.ApiDeelService;
import com.dkha.task.service.FaceTrackService;
import com.dkha.task.service.WebSocketContral;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.TimeoutUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @version V1.0
 * @Description: TODO(please write your description)
 * All rights 成都电科慧安
 * @Title: AsyncContral
 * @Package com.dkha.task.contral
 * @author: panhui
 * @date: 2020/1/3 17:34
 * @Copyright: 成都电科慧安
 */
@Component
@Slf4j
public class AsyncServiceImpl {


    @Autowired
    private WebSocketContral webSocketContral;

    /**
     * 卡口信息
     *
     * @return
     */
//    @Async  多綫程抛出異常
    public void bayonetInfo(String a, String b) {
        webSocketContral.sendMessage(a, b);
//        System.out.println(a+"-----"+b);
//        try {
//            Thread.sleep(10000);
//        }catch (Exception e){}
//        return null;
    }

    @Autowired
    private Gson gson;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private ApiDeelService apiDeelService;

    @Autowired
    private FaceTrackService faceTrackService;
    @Value("${face.minScore}")
    private Double minScore;

    /**
     * 轨迹分析统计每个摄像头的分组信息
     */
    @Async
    public void trackByCamera(String time, String cameraId) {
        Long deelNum = 0L;
        try {
            while (true) {
                String nowTime = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis());
//                log.error("綫程任務{},{},{}",nowTime,time,cameraId);
                if (!nowTime.equals(time)) {
                    //后续将redis里面的数据存到数据库做多时间的轨迹分析
                    if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) {
                        BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class);
                            try {
                                List<FaceTrackEntity> myList = new ArrayList<>();
                                for (String faceId : bayOnetCameraVO.getFeatIds()) {
                                    if (redisUtils.exists(RedisKeys.getCameraByFaceId(time, cameraId, faceId))) {
                                        List<PeopleVO> peopleVOList = gson.fromJson(redisUtils.get(RedisKeys.getCameraByFaceId(time, cameraId, faceId)).toString(), new TypeToken<List<PeopleVO>>() {
                                        }.getType());
                                        if (UtilValidate.isNotEmpty(peopleVOList)) {
                                            FaceTrackEntity faceTrackEntity = new FaceTrackEntity();
                                            faceTrackEntity.setIdPortrait(new Long(faceId));
                                            faceTrackEntity.setIdFaceCamera(new Long(bayOnetCameraVO.getCameraId()));
                                            faceTrackEntity.setIdFactory(new Long(bayOnetCameraVO.getAssociationLibraryId()));
                                            faceTrackEntity.setCharacterData(gson.toJson(peopleVOList.get(0)));
                                            faceTrackEntity.setLinkedData(gson.toJson(peopleVOList));
                                            faceTrackEntity.setPacketTime(time);
                                            faceTrackEntity.setTrajectoryThreshold(minScore);
                                            myList.add(faceTrackEntity);
                                        }
                                    }
                                }
                                if (UtilValidate.isNotEmpty(myList)) {
                                    faceTrackService.saveBatch(myList);
                                }
                            }catch (Exception e){}
                        deelLastDayTask(time, cameraId, bayOnetCameraVO);
                    } else {
                        deelTaskState(time, cameraId, deelNum);
                    }
                    //后续可以增加一个任务根据将数据库中本月的人物的数据进行人物关联
                    //清理掉没用的记录
                    break;
                }
                //使用过期时间来做是否异常检验，因为可能会遇到这边还没处理结束，定时器那边认为当前方法结束的情况
                //30秒过期
                if (!redisUtils.exists(RedisKeys.getCameraByExpired(time, cameraId))) {
                    redisUtils.set(RedisKeys.getCameraByExpired(time, cameraId), "运行", TimerData.expireTime);
                } else {
                    redisUtils.expire(RedisKeys.getCameraByExpired(time, cameraId), TimerData.expireTime);
                }
                //检索当前摄像头下所有预警的信息，处理的数据数量存入redis中防止程序重启后又要重新操作了
//                System.out.println("xxxxxxxxxxxx::"+redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString());
                if(redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId)))
                {
                    BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class);
                    deelNum = bayOnetCameraVO.getWarningNum();
                    apiDeelService.getApi(cameraId, time, deelNum, bayOnetCameraVO.getAssociationLibraryId());
                }
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                }
            }
        } catch (Exception e) {
            deelTaskState(time, cameraId, deelNum);
        }
    }

    /**
     * 时间过期清理多余的redis数据
     *
     * @param time
     * @param cameraId
     * @param bayOnetCameraVO
     */
    private void deelLastDayTask(String time, String cameraId, BayOnetCameraVO bayOnetCameraVO) {
        try {
            log.error("清理数据{},{}",time,cameraId);
            if(UtilValidate.isNotEmpty(bayOnetCameraVO.getFeatIds()))
            {
                bayOnetCameraVO.getFeatIds().forEach(e ->
                {
                    if (redisUtils.exists(RedisKeys.getCameraByFaceId(time, cameraId, e))) {
                        redisUtils.delete(RedisKeys.getCameraByFaceId(time, cameraId, e));
                    }
                });
            }
            if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) {
                redisUtils.delete(RedisKeys.getCameraByTrack(time, cameraId));
            }
        } catch (Exception e) {
            log.error("删除redis中过期数据异常{}", e.getMessage());
        }
    }

    /**
     * 处理任务状态和当前检测数量
     *
     * @param time
     * @param cameraId
     * @param deelNum
     */
    private void deelTaskState(String time, String cameraId, Long deelNum) {
        if (redisUtils.exists(RedisKeys.getCameraByTrack(time, cameraId))) {
            BayOnetCameraVO bayOnetCameraVO = gson.fromJson(redisUtils.get(RedisKeys.getCameraByTrack(time, cameraId)).toString(), BayOnetCameraVO.class);
            bayOnetCameraVO.setWarningNum(deelNum);
            redisUtils.set(RedisKeys.getCameraByTrack(time, cameraId), gson.toJson(bayOnetCameraVO));
        }
        if (redisUtils.exists(RedisKeys.getCameraByExpired(time, cameraId))) {
            redisUtils.delete(RedisKeys.getCameraByExpired(time, cameraId));
        }
    }
}
